Completed
Push — master ( 3800ca...54a022 )
by Sander
01:05
created

$j.ready   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 276

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 276
rs 8.2857

15 Functions

Rating   Name   Duplication   Size   Complexity  
B 0 31 2
A 0 8 3
A 0 3 1
A 0 7 2
B 0 31 3
A 0 11 3
A 0 50 1
A 0 6 2
B 0 36 3
B 0 11 6
A 0 7 2
A 0 17 2
A 0 5 1
A 0 12 1
A 0 14 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/* global API */
2
var $j = jQuery.noConflict();
3
$j(document).ready(function () {
4
    var _this = this;
5
6
    function removePasswordPicker() {
7
        $j('#passwordPickerIframe').remove();
8
    }
9
    _this.removePasswordPicker = removePasswordPicker;
10
11
    function enterLoginDetails(login) {
12
        var username = (login.username.trim() !== '' ) ? login.username : login.email;
13
14
        fillPassword(username, login.password);
15
        if ($j('#passwordPickerIframe').is(':visible')) {
16
            removePasswordPicker();
17
        }
18
    }
19
20
    _this.enterLoginDetails = enterLoginDetails;
21
22
23
    function showPasswordPicker(form) {
24
        var loginField = $j(form[0]);
25
        var loginFieldPos = loginField.offset();
26
        var passwordField = $j(form[1]);
27
        var passwordFieldPos = passwordField.offset();
28
29
        var left = loginFieldPos.left;
30
        var top = loginFieldPos.top;
31
32
        if (passwordFieldPos.top > loginFieldPos.top) {
33
            //console.log('login fields below each other')
34
            top = passwordFieldPos.top + passwordField.height() + 10;
35
36
        } else {
37
            // console.log('login fields next to each other')
38
            top = top + loginField.height() + 10;
39
        }
40
41
        var position = $j(form[1]).position();
0 ignored issues
show
Unused Code introduced by
The assignment to variable position seems to be never used. Consider removing it.
Loading history...
42
        var pickerUrl = API.extension.getURL('/html/inject/password_picker.html');
43
44
        $j(document.body).after('<iframe id="passwordPickerIframe" scrolling="no" height="400" width="350" frameborder="0" src="'+ pickerUrl +'"></iframe>');
45
46
        var picker = $j('#passwordPickerIframe');
47
        picker.css('position', 'absolute');
48
        picker.css('left', left);
49
        picker.css('z-index', 999);
50
        picker.css('top', top);
51
        // picker.css('width', $j(form).width());
52
53
    }
54
55
    function createFormIcon(el, form) {
56
        var offset = el.offset();
0 ignored issues
show
Unused Code introduced by
The assignment to variable offset seems to be never used. Consider removing it.
Loading history...
57
        var width = el.width();
58
        var height = el.height()*1;
59
        var margin = (el.css('margin')) ? parseInt(el.css('margin').replace('px', '')) : 0;
0 ignored issues
show
Unused Code introduced by
The variable margin seems to be never used. Consider removing it.
Loading history...
60
        var padding = (el.css('padding')) ? parseInt(el.css('padding').replace('px', '')) : 0;
0 ignored issues
show
Unused Code introduced by
The variable padding seems to be never used. Consider removing it.
Loading history...
61
62
        var pickerIcon = 'data:image/png;base64,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';
63
64
65
66
        $j(el).css('background-image', 'url("'+ pickerIcon +'")');
67
        $j(el).css('background-size', 'contain');
68
        $j(el).css('background-repeat', 'no-repeat');
69
        $j(el).css('background-position-x', 'right');
70
71
        $j(el).bind('click',function (e) {
72
            var offsetX = e.offsetX;
73
            var offsetRight = (width - offsetX);
74
            if(offsetRight < height){
75
                showPasswordPicker(form);
76
            }
77
        });
78
79
        var onClick = function () {
80
            showPasswordPicker(form);
81
        };
82
83
        $j(el).click(onClick);
84
85
    }
86
87
    function createPasswordPicker(form) {
88
        for (var i = 0; i < form.length; i++) {
89
            var el = $j(form[i]);
90
            createFormIcon(el, form);
91
92
        }
93
    }
94
95
    function updatePositions() {
96
        $j('.passwordPickerIcon').remove();
97
        var forms = getLoginFields();
98
        for (var f = 0; f < forms.length; f++) {
99
            var form = forms[f];
100
            for (var i = 0; i < form.length; i++) {
101
                var el = $j(form[i]);
102
                createFormIcon(el, form);
103
            }
104
        }
105
    }
106
107
108
    function togglePasswordPicker(e) {
109
        if (e.target.className === "passwordPickerIcon" || e.target.className === "fa fa-key") {
110
            return;
111
        }
112
        var picker = $j('#passwordPickerIframe');
113
        if (!picker.is(e.target) && picker.has(e.target).length === 0) {
114
            if (picker) {
115
                picker.remove();
116
            }
117
        }
118
    }
119
120
    function formSubmitted(fields) {
121
        var user = fields[0].value;
122
        var pass = fields[1].value;
123
        var params = {
124
            username: user,
125
            password: pass
126
        };
127
        //Disable password mining
128
        //$j(fields[1]).attr('type', 'hidden');
129
        API.runtime.sendMessage(API.runtime.id, {method: "minedForm", args: params});
130
131
    }
132
133
    function inIframe() {
134
        try {
135
            return window.self !== window.top;
136
        } catch (e) {
137
            return true;
138
        }
139
    }
140
141
142
    function checkForMined() {
143
        if (inIframe()) {
144
            return;
145
        }
146
        if(getLoginFields()){
147
            return;
148
        }
149
150
        API.runtime.sendMessage(API.runtime.id, {method: "getMinedData"}).then(function (data) {
151
            if (!data) {
152
                return;
153
            }
154
            if (data.hasOwnProperty('username') && data.hasOwnProperty('password') && data.hasOwnProperty('url')) {
155
                var doorhanger = $j('<div id="password-toolbar" class="container" style="display: none;">' +
156
                    '<span class="toolbar-text">' + data.title + ' ' + data.username + ' at ' + data.url + '</span></div>');
157
158
                var btnText = (data.guid === null) ? 'Save' : 'Update';
159
                var btnSave = $j('<button class="btn btn-success">' + btnText + '</button>');
160
                var btnCancel = $j('<button class="btn btn-default">Cancel</button>');
161
                btnSave.click(function () {
162
                    //closeToolbar();
163
                    API.runtime.sendMessage(API.runtime.id, {method: "saveMined"});
164
                });
165
166
                btnCancel.click(function () {
167
                    closeToolbar();
168
                    API.runtime.sendMessage(API.runtime.id, {method: "clearMined"});
169
                });
170
171
                doorhanger.append(btnCancel).append(btnSave);
172
                $j('#password-toolbar').remove();
173
                $j('body').append(doorhanger);
174
                $j('#password-toolbar').slideDown();
175
            }
176
        });
177
    }
178
179
    function minedLoginSaved(args) {
180
        // If the login added by the user then this is true
181
        if (args.selfAdded) {
182
            enterLoginDetails(args.credential);
183
            return;
184
        }
185
        if ($j('#password-toolbar').is(':visible')) {
186
            var action = (args.updated) ? 'updated' : 'saved';
187
            $j('#password-toolbar').html('Credential ' + action + '!');
188
            setTimeout(function () {
189
                closeToolbar();
190
            }, 2500);
191
        }
192
    }
193
194
    _this.minedLoginSaved = minedLoginSaved;
195
196
    function closeToolbar() {
197
        $j('#password-toolbar').slideUp(400, function () {
198
            $j('#password-toolbar').remove();
199
        });
200
    }
201
202
203
    function init() {
204
        $j(document).unbind('click', togglePasswordPicker);
205
        checkForMined();
206
        API.runtime.sendMessage(API.runtime.id, {method: 'getRuntimeSettings'}).then(function (result) {
207
            var disablePasswordPicker = result.disablePasswordPicker;
208
209
            var loginFields = getLoginFields();
210
            if (loginFields.length > 0) {
211
                //@TODO prevent chrome from captuting pw's: http://stackoverflow.com/questions/27280461/prevent-chrome-from-prompting-to-save-password-from-input-box
212
                for (var i = 0; i < loginFields.length; i++) {
213
                    var form = getFormFromElement(loginFields[i][0]);
214
                    if(!disablePasswordPicker) {
215
                        createPasswordPicker(loginFields[i], form);
0 ignored issues
show
Bug introduced by
The call to createPasswordPicker seems to have too many arguments starting with form.
Loading history...
216
                    }
217
                    //Password miner
218
                    /* jshint ignore:start */
219
                    $j(form).submit((function (loginFields) {
220
                        return function () {
221
                            formSubmitted(loginFields);
222
                        };
223
                    })(loginFields[i]));
224
                    /* jshint ignore:end */
225
                }
226
227
                var url = window.location.href; //@TODO use a extension function
228
                API.runtime.sendMessage(API.runtime.id, {
229
                    method: "getCredentialsByUrl",
230
                    args: [url]
231
                }).then(function (logins) {
232
                    //console.log('Found ' + logins.length + ' logins for this site');
233
                    if (logins.length === 1) {
234
                        API.runtime.sendMessage(API.runtime.id, {method: 'isAutoFillEnabled'}).then(function (isEnabled) {
235
                            if (isEnabled) {
236
                                enterLoginDetails(logins[0]);
237
                            }
238
                        });
239
                    }
240
241
                });
242
            }
243
244
        });
245
246
        $j(document).click(togglePasswordPicker);
247
        $j(window).on('resize', function () {
248
            if (getLoginFields().length > 0) {
249
                updatePositions();
250
            }
251
        });
252
    }
253
254
    var readyStateCheckInterval = setInterval(function () {
255
        if (document.readyState === "complete") {
256
            clearInterval(readyStateCheckInterval);
257
            API.runtime.sendMessage(API.runtime.id, {method: 'getMasterPasswordSet'}).then(function (result) {
258
                if (result) {
259
                    init();
260
                } else {
261
                    console.log('[Passman extension] Stopping, vault key not set');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
262
                }
263
            });
264
265
            // var body = document.getElementsByTagName('body')[0];
266
            // observeDOM(body, function () {
267
            //     //init()
268
            // });
269
        }
270
    }, 10);
271
272
    API.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
0 ignored issues
show
Unused Code introduced by
The parameter sendResponse is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
273
        console.log('Method call', msg.method);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
274
        if(_this[msg.method]) {
275
            _this[msg.method](msg.args, sender);
276
        }
277
    });
278
});